package com.huiquan.icd.service;

import com.huiquan.analysis.domain.User;
import com.huiquan.framework.base.BaseService;
import com.huiquan.framework.base.ReturnCode;
import com.huiquan.framework.base.ReturnData;
import com.huiquan.framework.utils.GetListUtil;
import com.huiquan.framework.utils.RespHeaderUtil;
import com.huiquan.framework.utils.ReturnUtil;
import com.huiquan.icd.dao.IcdDiseaseNationalStdDao;
import com.huiquan.icd.domain.IcdDiseaseNationalStd;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

@Service
public class IcdDiseaseNationalStdService extends BaseService {

	@Autowired
	private IcdDiseaseNationalStdDao icdDiseaseNationalStdDao;

	public ModelAndView list(Integer start, String codeSearch, String exactSearchFlag, String countPerPageStr,String detailCode,String category,String detailModifyName) {
		boolean exactFlag = exactSearchFlag != null && exactSearchFlag.equals("1");
		Map<String, Object> param = new HashMap<>();
		if (codeSearch != null && !codeSearch.isEmpty()) {
			param.put("codeSearch", exactFlag ? codeSearch : "%" + codeSearch + "%");
		}
		if (detailCode != null && !detailCode.isEmpty()) {
			param.put("detailCode", exactFlag ? detailCode : "%" + detailCode + "%");
		}
		if (category != null && !category.isEmpty()) {
			param.put("category", exactFlag ? category : "%" + category + "%");
		}
		if (detailModifyName != null && !detailModifyName.isEmpty()) {
			param.put("detailModifyName", exactFlag ? detailModifyName : "%" + detailModifyName + "%");
		}
		int totalSize = icdDiseaseNationalStdDao.retrieveSize(param);

		Map<String, Integer> pageNo = new HashMap<>();
		if (countPerPageStr != null && !countPerPageStr.isEmpty()) {
			int countPerPage = Integer.parseInt(countPerPageStr);
			pageNo = GetListUtil.getPageNoParam(totalSize, start + "", countPerPage);
			param.put("countPerPage", countPerPage);
		} else {
			pageNo = GetListUtil.getPageNoParam(totalSize, start + "");
		}
		int endPage = pageNo.get("endPage");
		start = pageNo.get("start");
		int startIndex = pageNo.get("startIndex");

		List<IcdDiseaseNationalStd> list = new ArrayList<>();

		if (startIndex < totalSize) {
			param.put("startIndex", startIndex);
			list = icdDiseaseNationalStdDao.retrieveList(param);
		}

		Map<String, String> showSearch = new LinkedHashMap<>();
		showSearch.put("codeSearch", "细目名称");
		showSearch.put("detailCodeStr", "细目code");
		showSearch.put("category", "一级");
		showSearch.put("detailModifyName", "细目原名称");

		Map<String, String> searchMap = new HashMap<>();
		searchMap.put("codeSearch", codeSearch);
		searchMap.put("detailCode", detailCode);
		searchMap.put("category",category);
		searchMap.put("detailModifyName", detailModifyName);
		
		Map<String, Object> map = GetListUtil.getReturnMap2(totalSize, start, startIndex, endPage, list, searchMap);
		map.put("showSearch", showSearch);
		map.put("showSearchValue", searchMap);
		map.put("exactSearchFlag", exactSearchFlag);
		return new ModelAndView("icd/index", map);
	}

	public ModelAndView preEdit(String id) {
		Map<String, Object> map = new HashMap<>();
		map.put("id", id);
		IcdDiseaseNationalStd value = icdDiseaseNationalStdDao.retrieveObjectById(Long.parseLong(id));
		map.put("detailName", value.getDetailName());
		map.put("categoryName", value.getCategoryName());
		map.put("disable", value.getDisable());
		map.put("detailModifyName", value.getDetailModifyName());
		map.put("detailCode", value.getDetailCode());
		map.put("detailAccessoryCode", value.getDetailAccessoryCode());
		map.put("chapterSequence", value.getChapterSequence());
		map.put("chapterCode", value.getChapterCode());
		map.put("chapterName", value.getChapterName());
		map.put("sectionCode", value.getSectionCode());
		map.put("sectionName", value.getSectionName());
		map.put("gpCode", value.getGpCode());
		map.put("gpAccessoryCode", value.getGpAccessoryCode());
		map.put("gpName", value.getGpName());
		map.put("suborderCode", value.getSuborderCode());
		map.put("suborderAccessoryCode", value.getSuborderAccessoryCode());
		map.put("suborderName", value.getSuborderName());

		return new ModelAndView("icd/disease_national_std_edit", map);
	}

	public ReturnData changeDisable(String id, User user, String disable) {
		if (user != null) {
			icdDiseaseNationalStdDao.changeDisable(id,user.getUserId(),disable);
		}
		return ReturnUtil.success();
	}
	public void export(HttpServletResponse resp, String detailCode, String detailAccessoryCode, String detailName,
			String categoryName, String disable, String detailModifyName, String chapterSequence, String chapterCode,
			String chapterName, String sectionCode, String sectionName, String gpCode, String gpAccessoryCode,
			String gpName, String suborderCode, String suborderAccessoryCode, String suborderName) throws Exception {
		// 设置respons的头信息
		RespHeaderUtil.setXlsxResp(resp, "国标疾病");

		Workbook workbook = new XSSFWorkbook(); // 创建文档

		// 根据property和keyword获取同义词列表
		Map<String, Object> param = new HashMap<>();
		List<IcdDiseaseNationalStd> synonymList = icdDiseaseNationalStdDao.retrieveList(param);

		Sheet sheet = workbook.createSheet("国标疾病"); // 创建Sheet
		// 循环写入数据
		for (int i = 0; i < synonymList.size(); i++) {
			Row row = sheet.createRow(i);
			if (i == 0) {
				// 根据选中的设置标题
				setExportTitle(row, detailCode, detailAccessoryCode, detailName, chapterSequence, chapterCode,
						chapterName, sectionCode, sectionName, gpCode, gpAccessoryCode, gpName, suborderCode,
						suborderAccessoryCode, suborderName);
			} else {
				// 根据选中设置正式数据
				IcdDiseaseNationalStd vocabElement = synonymList.get(i);
				setExportContent(row, detailCode, detailAccessoryCode, detailName, chapterSequence, chapterCode,
						chapterName, sectionCode, sectionName, gpCode, gpAccessoryCode, gpName, suborderCode,
						suborderAccessoryCode, suborderName, vocabElement);

			}

		}

		OutputStream os = resp.getOutputStream();
		workbook.write(os);

		os.close();
		workbook.close();
	}

	private void setExportContent(Row row, String detailCode, String detailAccessoryCode, String detailName,
			String chapterSequence, String chapterCode, String chapterName, String sectionCode, String sectionName,
			String gpCode, String gpAccessoryCode, String gpName, String suborderCode, String suborderAccessoryCode,
			String suborderName, IcdDiseaseNationalStd vocabElement) {
		Cell cell = row.createCell(0);
		cell.setCellValue(vocabElement.getId() + "");
		int j = 1;
		if ("1".equals(detailName)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getDetailName());
			j++;
		}
		cell = row.createCell(j);
		cell.setCellValue(vocabElement.getCategoryName());
		j++;
		cell = row.createCell(j);
		cell.setCellValue(vocabElement.getDisable());
		j++;
		cell = row.createCell(j);
		cell.setCellValue(vocabElement.getDetailModifyName());
		j++;
		if ("1".equals(detailCode)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getDetailCode());
			j++;
		}
		if ("1".equals(detailAccessoryCode)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getDetailAccessoryCode());
			j++;
		}

		if ("1".equals(chapterSequence)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getChapterSequence());
			j++;
		}
		if ("1".equals(chapterCode)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getChapterCode());
			j++;
		}
		if ("1".equals(chapterName)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getChapterName());
			j++;
		}
		if ("1".equals(sectionCode)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getSectionCode());
			j++;
		}
		if ("1".equals(sectionName)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getSectionName());
			j++;
		}
		if ("1".equals(gpCode)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getGpCode());
			j++;
		}
		if ("1".equals(gpAccessoryCode)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getGpAccessoryCode());
			j++;
		}
		if ("1".equals(gpName)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getGpName());
			j++;
		}
		if ("1".equals(suborderCode)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getSuborderCode());
			j++;
		}
		if ("1".equals(suborderAccessoryCode)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getSuborderAccessoryCode());
			j++;
		}
		if ("1".equals(suborderName)) {
			cell = row.createCell(j);
			cell.setCellValue(vocabElement.getSuborderName());
			j++;
		}
	}

	private void setExportTitle(Row row, String detailCode, String detailAccessoryCode, String detailName,
			String chapterSequence, String chapterCode, String chapterName, String sectionCode, String sectionName,
			String gpCode, String gpAccessoryCode, String gpName, String suborderCode, String suborderAccessoryCode,
			String suborderName) {
		int j = 1;
		Cell cell = row.createCell(0);
		cell.setCellValue("id");
		if ("1".equals(detailName)) {
			cell = row.createCell(j);
			cell.setCellValue("细目名称");
			j++;
		}
		cell = row.createCell(j);
		cell.setCellValue("一级");
		j++;
		cell = row.createCell(j);
		cell.setCellValue("disable");
		j++;
		cell = row.createCell(j);
		cell.setCellValue("细目原名称");
		j++;
		if ("1".equals(detailCode)) {
			cell = row.createCell(j);
			cell.setCellValue("细目code");
			j++;
		}
		if ("1".equals(detailAccessoryCode)) {
			cell = row.createCell(j);
			cell.setCellValue("细目附属码");
			j++;
		}

		if ("1".equals(chapterSequence)) {
			cell = row.createCell(j);
			cell.setCellValue("章序列");
			j++;
		}
		if ("1".equals(chapterCode)) {
			cell = row.createCell(j);
			cell.setCellValue("章code");
			j++;
		}
		if ("1".equals(chapterName)) {
			cell = row.createCell(j);
			cell.setCellValue("章名称");
			j++;
		}
		if ("1".equals(sectionCode)) {
			cell = row.createCell(j);
			cell.setCellValue("节code");
			j++;
		}
		if ("1".equals(sectionName)) {
			cell = row.createCell(j);
			cell.setCellValue("节名称");
			j++;
		}
		if ("1".equals(gpCode)) {
			cell = row.createCell(j);
			cell.setCellValue("类目code");
			j++;
		}
		if ("1".equals(gpAccessoryCode)) {
			cell = row.createCell(j);
			cell.setCellValue("类目附属码");
			j++;
		}
		if ("1".equals(gpName)) {
			cell = row.createCell(j);
			cell.setCellValue("类目名称");
			j++;
		}
		if ("1".equals(suborderCode)) {
			cell = row.createCell(j);
			cell.setCellValue("亚目code");
			j++;
		}
		if ("1".equals(suborderAccessoryCode)) {
			cell = row.createCell(j);
			cell.setCellValue("亚目附属码");
			j++;
		}
		if ("1".equals(suborderName)) {
			cell = row.createCell(j);
			cell.setCellValue("亚目名称");
			j++;
		}
	}

	public ReturnData nationalStdImport(MultipartFile file, User user) throws Exception {

		// 获取同义词构建对象
		Map<String, Object> param = new HashMap<>();
		param.put("type", 1);
		param.put("property", "di");
		// 获取文件流，解析文件
		InputStream inputStream = file.getInputStream();
		StringBuffer err1 = new StringBuffer();
		StringBuffer err2 = new StringBuffer();

		LOGGER.info("解析文档开始");
		@SuppressWarnings("resource")
		Workbook workbook = new XSSFWorkbook(inputStream);
		Sheet sheet = workbook.getSheetAt(0);
		LOGGER.info("解析文档结束");

		// 获取原有的数据
		Map<String, IcdDiseaseNationalStd> oldMap = getOldNationalStd();
		// 需要update的
		List<IcdDiseaseNationalStd> updateList = new ArrayList<>();
		// 处理每一行
		int i = 1;
		// id的列号
		int idIndex = 0;
		int categoryNameIndex = 0;
		int disableIndex = 0;
		int detailModifyNameIndex = 0;
		LOGGER.info("开始校验数据");
		for (Row row : sheet) {
			// 第一行是标题
			if (i == 1) {
				int rowNum = row.getLastCellNum();
				for (int j = 0; j < rowNum; j++) {
					if ("id".equals(getCellNum(row, j))) {
						idIndex = j;
					}
					if ("一级".equals(getCellNum(row, j))) {
						categoryNameIndex = j;
					}
					if ("disable".equals(getCellNum(row, j))) {
						disableIndex = j;
					}
					if ("细目原名称".equals(getCellNum(row, j))) {
						detailModifyNameIndex = j;
					}
				}
			} else {
				String id = "";
				String categoryName = "";
				String disable = "";
				String detailModifyName = "";
				id = getCellNum(row, idIndex);
				if (categoryNameIndex > 0) {
					categoryName = getCellNum(row, categoryNameIndex);
				}
				if (disableIndex > 0) {
					disable = getCellNum(row, disableIndex);
				}
				if (detailModifyNameIndex > 0) {
					detailModifyName = getCellNum(row, detailModifyNameIndex);
				}
				if (StringUtils.isNotBlank(id) && StringUtils.isNumeric(id)) {
					IcdDiseaseNationalStd value = new IcdDiseaseNationalStd();
					value.setId(Long.parseLong(id));
					if (categoryNameIndex > 0) {
						value.setCategoryName(categoryName);
					}
					if (disableIndex > 0) {
						value.setDisable(disable);
					}
					if (detailModifyNameIndex > 0) {
						value.setDetailModifyName(detailModifyName);
					}
					// 有主code必须有disable ,只有附属码的1级和disable为空
					IcdDiseaseNationalStd oldValue = oldMap.get(id);
					if (StringUtils.isNotBlank(oldMap.get(id).getDetailCode()) && StringUtils.isBlank(disable)
							&& disableIndex > 0) {
						if (err1.length() == 0) {
							err1.append("下列行数主code必须有disable:");
						}
						err1.append(i).append(";");
					}
					// disable = 0,1 必须有一级
					if (disableIndex > 0 && categoryNameIndex > 0) {
						if(("0".equals(disable)||"1".equals(disable)) && StringUtils.isBlank(categoryName) && StringUtils.isNotBlank(oldValue.getDetailCode())){
							if (err2.length() == 0) {
								err2.append("下列列disable=0,1，必须有一级:");
							}
							err2.append(i).append(";");
						}
					}
					// 只有附属码的1级和disable为空
					if (StringUtils.isBlank(oldValue.getDetailCode())
							&& StringUtils.isNotBlank(oldValue.getDetailAccessoryCode())) {
						value.setCategoryName("");
						value.setDisable("");
					}
					boolean updateFlag = false;
					if (disableIndex > 0) {
						if (!StringUtils.equals(value.getDisable(), oldValue.getDisable())) {
							updateFlag = true;
						}
					}
					if (categoryNameIndex > 0) {
						if (!StringUtils.equals(value.getCategoryName(), oldValue.getCategoryName())) {
							updateFlag = true;
						}
					}
					if (detailModifyNameIndex > 0) {
						if (!StringUtils.equals(value.getDetailModifyName(), oldValue.getDetailModifyName())) {
							updateFlag = true;
						}
					}
					if (updateFlag) {
						value.setModifierId(user.getUserId()+"");
						updateList.add(value);
					}
				}
			}
			i++;
		}
		LOGGER.info("数据校验结束");
		if (err1.length() > 0 || err2.length()>0) {
			ReturnCode rc = ReturnCode.DYNAMIC_DESC_EXCEPTION;
			rc.setDesc(err1.toString()+"\n"+err2.toString());
			return ReturnUtil.fail(rc);
		}
		LOGGER.info("开始更新");
		for (IcdDiseaseNationalStd updateValue : updateList) {
			icdDiseaseNationalStdDao.update(updateValue);
		}
		LOGGER.info("更新结束");

		return ReturnUtil.success();
	}

	private Map<String, IcdDiseaseNationalStd> getOldNationalStd() {
		Map<String, IcdDiseaseNationalStd> rtn = new HashMap<>();
		List<IcdDiseaseNationalStd> list = icdDiseaseNationalStdDao.retrieveList();
		for (IcdDiseaseNationalStd value : list) {
			rtn.put(value.getId() + "", value);
		}
		return rtn;
	}

	private String getCellNum(Row row, int num) {
		Cell cell = row.getCell(num);
		String index = "";
		if (cell != null) {
			cell.setCellType(Cell.CELL_TYPE_STRING);
			index = cell.getStringCellValue().trim();
		}
		return index;
	}

	public ReturnData submitEdit(String id, String disable, String categoryName, String detailModifyName, User user) {
		// TODO Auto-generated method stub
		IcdDiseaseNationalStd updateValue = new IcdDiseaseNationalStd();
		updateValue.setId(Long.parseLong(id));
		updateValue.setDisable(disable);
		updateValue.setCategoryName(categoryName);
		updateValue.setDetailModifyName(detailModifyName);
		updateValue.setModifierId(user.getUserId()+"");
		icdDiseaseNationalStdDao.update(updateValue);

		return ReturnUtil.success();
	}
}
